package com.hzdracom.epubreader.util;

import android.content.Context;
import android.text.TextUtils;

import com.hzdracom.epubreader.consts.EpubConst;
import com.shwread.android.qysw.QyReaderApp;
import com.shwread.http.util.Logger;

import net.nightwhistler.htmlspanner.FontFamily;
import net.nightwhistler.htmlspanner.style.Style.BorderStyle;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import logic.util.FileUtil;

/**
 * CSS自定义样式解析
 */
public class CSSHelp {

    /******************** body *******************/
    public static class Body {
        public static final String TAG_STYLE_ID = "body";
        public static final String TAG_BACKGROUND = "background";
        public static final String TAG_FONT_SIZE = "font-size";
        public static final String TAG_LINE_HEIGHT = "line-height";

        public int font_size;
        public int line_height;
        public String background;

        @Override
        public String toString() {
            return "Body [font_size=" + font_size + ", line_height=" + line_height + ", background=" + background + "]";
        }
    }

    /******************** someonesaid 引文*******************/
    public static class Someonesaid {
        public static final String TAG_STYLE_ID = "someonesaid";
        public static final String TAG_TEXT_INDENT = "text-indent";
        public static final String TAG_FONT_FAMILY = "font-family";
        public static final String TAG_PADDING = "padding";
        public static final String TAG_BORDER_TOP_WIDTH = "border-top-width";
        public static final String TAG_BORDER_TOP_STYLE = "border-top-style";
        public static final String TAG_BORDER_TOP_COLOR = "border-top-color";
        public static final String TAG_BORDER_BOTTOM_WIDTH = "border-bottom-width";
        public static final String TAG_BORDER_BOTTOM_STYLE = "border-bottom-style";
        public static final String TAG_BORDER_BOTTOM_COLOR = "border-bottom-color";

        public int text_indent;
        public int padding;
        public FontFamily font_family;
        public String border_top_color;
        public BorderStyle border_top_style;
        public int border_top_width;
        public String border_bottom_color;
        public BorderStyle border_bottom_style;
        public int border_bottom_width;

        @Override
        public String toString() {
            return "Someonesaid [text_indent=" + text_indent + ", padding=" + padding + ", font_family=" + font_family + ", border_top_color=" + border_top_color + ", border_top_style=" + border_top_style + ", border_top_width=" + border_top_width + ", border_bottom_color=" + border_bottom_color + ", border_bottom_style=" + border_bottom_style + ", border_bottom_width=" + border_bottom_width + "]";
        }
    }

    /******************** summary 摘要*******************/
    public static class Summary {
        public static final String TAG_STYLE_ID = "summary";
        public static final String TAG_MARGIN_LEFT = "margin-left";
        public static final String TAG_MARGIN_RIGHT = "margin-right";

        public int margin_left;
        public int margin_right;

        @Override
        public String toString() {
            return "Summary [margin_left=" + margin_left + ", margin_right=" + margin_right + "]";
        }
    }

    private static Body body;

    public static Body getBody() {
        if (null == body) {
            body = new Body();
            body.background = "#FFFFFF";
            body.font_size = 16;
            body.line_height = 22;
        }
        return body;
    }

    private static Someonesaid someonesaid;

    public static Someonesaid getSomeonesaid() {
        if (null == someonesaid) {
//			final String defaultColor = "#FF00FF";
            final String defaultColor = "#BBD575";
            someonesaid = new Someonesaid();
            someonesaid.border_top_color = defaultColor;
            someonesaid.border_top_style = BorderStyle.SOLID;
            someonesaid.border_top_width = 5;
            someonesaid.border_bottom_color = defaultColor;
            someonesaid.border_bottom_style = BorderStyle.SOLID;
            someonesaid.border_bottom_width = 1;
            someonesaid.font_family = QyReaderApp.getFontFamily();
            someonesaid.padding = 5;
            someonesaid.text_indent = 10;
        }
        return someonesaid;
    }

    private static Summary summary;

    public static Summary getSummary() {
        if (null == summary) {
            summary = new Summary();
            summary.margin_left = 28;
            summary.margin_right = 28;
        }
        return summary;
    }

    public static void parse(Context context, String cssPath) {
        if (TextUtils.isEmpty(cssPath)) {
            return;
        }
        InputStream is = null;
        try {
            is = new FileInputStream(cssPath);
            parse(context, is);
        } catch (Exception e) {
            System.err.println("CSS解析异常:" + e);
        } finally {
            if (null != is) {
                try {
                    is.close();
                    is = null;
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void parse(Context context, InputStream inputStream) {
        if (null == inputStream) {
            return;
        }
        InputStreamReader inputreader = null;
        BufferedReader buffreader = null;
        try {
            inputreader = new InputStreamReader(inputStream);
            buffreader = new BufferedReader(inputreader);
            String line;
            boolean hasNextParse = true;

            boolean hasBodyAttribute = false;
            boolean hasSummaryAttribute = false;
            boolean hasSomeonesaidAttribute = false;

            boolean hasBodyParseFinish = false;
            boolean hasSummaryParseFinish = false;
            boolean hasSomeonesaidParseFinish = false;
            //分行读取
//          while (( line = buffreader.readLine()) != null) { }
            while (hasNextParse) {
                line = buffreader.readLine();

                if (null != line && line.contains(Body.TAG_STYLE_ID)) {
                    hasBodyAttribute = true;
                    body = new Body();
                }
                if (hasBodyAttribute && null != line) {
                    parseBodyAttribute(context, line, body);
                    if (line.trim().equals("}")) {
                        hasBodyAttribute = false;
                        hasBodyParseFinish = true;
                    }
                }

                if (null != line && line.contains(Summary.TAG_STYLE_ID)) {
                    hasSummaryAttribute = true;
                    summary = new Summary();
                }
                if (hasSummaryAttribute && null != line) {
                    parseSummaryAttribute(context, line, summary);
                    hasSummaryAttribute = false;
                    hasSummaryParseFinish = true;
                }

                if (null != line && line.contains(Someonesaid.TAG_STYLE_ID)) {
                    hasSomeonesaidAttribute = true;
                    someonesaid = new Someonesaid();
                }
                if (hasSomeonesaidAttribute && null != line) {
                    parseSomeonesaidAttribute(context, line, someonesaid);
                    if (line.trim().equals("}")) {
                        hasSomeonesaidAttribute = false;
                        hasSomeonesaidParseFinish = true;
                    }
                }

                if (hasBodyParseFinish && hasSummaryParseFinish && hasSomeonesaidParseFinish) {
                    hasNextParse = false;
//					Logger.d("CSS解析完成："+body.toString()+"\n"+summary.toString()+"\n"+someonesaid.toString());
                    System.out.println("CSS解析完成：" + body.toString() + "\n" + summary.toString() + "\n" + someonesaid.toString());
                }
            }
        } catch (Exception e) {
            System.err.println("CSS解析异常:" + e);
//			Logger.e("CSS解析异常",e);
        } finally {
            if (null != buffreader) {
                try {
                    buffreader.close();
                    buffreader = null;
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != inputreader) {
                try {
                    inputreader.close();
                    inputreader = null;
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private static void parseBodyAttribute(Context context, String line, Body object) {
        if (!line.contains(":") || null == object) return;
        final String[] values = line.split(":");
        final String key = values[0].trim();
        final String value = values[1].trim().replace(";", "");
        switch (key) {
            case Body.TAG_BACKGROUND:
                object.background = value;
                break;
            case Body.TAG_FONT_SIZE:
                object.font_size = parsePX(value);
                break;
            case Body.TAG_LINE_HEIGHT:
                object.line_height = parsePX(value);
                break;
        }
    }

    private static void parseSummaryAttribute(Context context, String line, Summary object) {
        if (TextUtils.isEmpty(line) || null == object) return;
        final String[] items = line.split(" ");
        for (String item : items) {
            if (TextUtils.isEmpty(item) || !item.contains(":")) {
                continue;
            }
            final String[] values = item.split(":");
            final String key = values[0].trim();
            final String value = values[1].trim().replace(";", "");
            if (key.equals(Summary.TAG_MARGIN_LEFT)) {
                object.margin_left = parsePX(value);
            } else if (key.equals(Summary.TAG_MARGIN_RIGHT)) {
                object.margin_right = parsePX(value);
            }
        }
    }

    private static void parseSomeonesaidAttribute(Context context, String line, Someonesaid object) {
        if (!line.contains(":") || null == object) return;
        final String[] values = line.split(":");
        final String key = values[0].trim();
        final String value = values[1].trim().replace(";", "");
        if (key.equals(Someonesaid.TAG_TEXT_INDENT)) {
            object.text_indent = parsePX(value);
        } else if (key.equals(Someonesaid.TAG_PADDING)) {
            object.padding = parsePX(value);
        } else if (key.equals(Someonesaid.TAG_BORDER_TOP_WIDTH)) {
            object.border_top_width = parsePX(value);
        } else if (key.equals(Someonesaid.TAG_BORDER_TOP_STYLE)) {
            object.border_top_style = parseBorderStyle(value);
        } else if (key.equals(Someonesaid.TAG_BORDER_TOP_COLOR)) {
            object.border_top_color = value;
        } else if (key.equals(Someonesaid.TAG_BORDER_BOTTOM_WIDTH)) {
            object.border_bottom_width = parsePX(value);
        } else if (key.equals(Someonesaid.TAG_BORDER_BOTTOM_STYLE)) {
            object.border_bottom_style = parseBorderStyle(value);
        } else if (key.equals(Someonesaid.TAG_BORDER_BOTTOM_COLOR)) {
            object.border_bottom_color = value;
        } else if (key.equals(Someonesaid.TAG_FONT_FAMILY) && value.contains("楷体")) {
            object.font_family = QyReaderApp.getFontFamily();
        }
    }

    private static int parsePX(String pxString) {
        pxString = pxString.replace("px", "");
        int value = -1;
        try {
            value = Integer.valueOf(pxString);
        } catch (NumberFormatException e) {
            e.printStackTrace();
        }
        return value;
    }

    private static BorderStyle parseBorderStyle(String style) {
        BorderStyle value = BorderStyle.SOLID;
        if (!TextUtils.isEmpty(style)) {
            switch (style) {
                case "solid":
                    value = BorderStyle.SOLID;
                    break;
                case "dashed":
                    value = BorderStyle.DASHED;
                    break;
                case "dotted":
                    value = BorderStyle.DOTTED;
                    break;
                case "double":
                    value = BorderStyle.DOUBLE;
                    break;
            }
        }
        return value;
    }


    /**
     * 解压css文件
     */
    public static void unZipCSS(long bookId) {
        final String savePath = EpubConst.EPUB_CSS_LOCAL_PATH + bookId + "/" + EpubConst.EPUB_CSS_NAME;
        final String epubPath = FileUtil.DownloadPath() + bookId + EpubConst.EPUB_SUFFIX;
        File file = new File(savePath);
        if (file.exists()) {
            return;
        }
        file.getParentFile().mkdirs();
        ZipInputStream inZip = null;
        try {
            inZip = new ZipInputStream(new FileInputStream(epubPath));
            ZipEntry zipEntry;
            String szName = "";
            boolean cssExists = false;
            while ((zipEntry = inZip.getNextEntry()) != null && !cssExists) {
                szName = zipEntry.getName();
                if (!zipEntry.isDirectory() && szName.equals(EpubConst.EPUB_CSS_FULLNAME)) {
                    file.createNewFile();
                    FileOutputStream out = new FileOutputStream(file);
                    int len;
                    byte[] buffer = new byte[1024];
                    while ((len = inZip.read(buffer)) != -1) {
                        out.write(buffer, 0, len);
                        out.flush();
                    }
                    out.close();
                    cssExists = true;
                }
            }
            inZip.close();
            Logger.d("css文件解压完成");
        } catch (Exception e) {
            Logger.e("css文件解压异常：" + e.getMessage());
            e.printStackTrace();
        }
    }
}
